#include "CTimer.h"
#include <QThread>
#include <QDateTime>

CTimer::CTimer()
{
	m_pThread = nullptr;
	m_bStart = false;
	m_bThreadRuning = false;
    m_uid = (quint64)this;
	Reset();
}
CTimer::~CTimer()
{}

quint64 CTimer::GetKey()
{
	return m_uid;
}
void CTimer::SetCB(PTIMERCALLBACK pcb)
{
	m_pcb = pcb;
}
void CTimer::SetGapTicks(int nTicks)
{
	m_nGapTicks = nTicks;
}
void CTimer::SetUserData(quint64 UserData)
{
	m_UseData = UserData;
}
void CTimer::SetState(int* pState)
{
	m_pState = pState;
}
void CTimer::Reset()
{
	Stop();
	SetCB(nullptr);
	SetGapTicks(-1);
	SetUserData(0);
	SetState(nullptr);
}
void CTimer::Start()
{
	if (m_bStart)
	{
		return;
	}
	///////////////////////
	while (m_bThreadRuning)
	{
        QThread::msleep(m_nGapTicks / 2);
	}
	if (m_pThread)
	{
		m_pThread->join();
		delete m_pThread;
		m_pThread = nullptr;
	}
	///////////////////////

	m_bStart = true;

	m_pThread = new thread(ThreadCount, this);

	while (!m_bThreadRuning)
	{
        QThread::msleep(1);
	}
}
void CTimer::Stop()
{
	if (!m_bStart)
	{
		return;
	}
	m_bStart = false;

	while (m_bThreadRuning)
	{
        QThread::msleep(100);
	}
}
void CTimer::NotifyChange()
{
	if (m_pcb)
	{
		m_pcb(m_uid, m_UseData);
	}
	if (m_pState)
	{
		++(*m_pState);
	}
}
void CTimer::ThreadCount(CTimer* pThis)
{
	pThis->m_bThreadRuning = true;

    qint64 llStart = QDateTime::currentMSecsSinceEpoch();

	int nSleepTicks = pThis->m_nGapTicks / 3;

	if (nSleepTicks > 50)
	{
		nSleepTicks = 50;
	}
	if (nSleepTicks < 1)
	{
		nSleepTicks = 1;
	}

	while (pThis->m_bStart)
	{
        qint64 llOff = QDateTime::currentMSecsSinceEpoch() - llStart;
		if (llOff >= pThis->m_nGapTicks)
		{
			pThis->NotifyChange();

            llStart = QDateTime::currentMSecsSinceEpoch();
		}
        QThread::msleep(nSleepTicks);
	}
	pThis->m_bThreadRuning = false;
}
